package com.xxl.controller.impl;

import com.xxl.controller.NoAuthenticationApi;
import com.xxl.dto.BlogCommentDto;
import com.xxl.dto.HomeDto;
import com.xxl.dto.UserDto;
import com.xxl.dto.vo.UserVo;
import com.xxl.service.BlogService;
import com.xxl.service.UserService;
import com.xxl.util.*;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 实现NoAuthenticationApi
 * @author xxl
 * @date 2023/4/2
 */
@RestController
@RequestMapping(value = "noAuth", produces = "application/json")
public class NoAuthenticationApiImpl implements NoAuthenticationApi<Map<String, Object>> {
    @Resource
    public UserService userService;
    @Resource
    public GlobalResult resultUtil;
    @Resource
    HttpServletResponse response;
    @Resource
    HttpServletRequest request;
    @Resource
    EmailUtil emailUtil;
    @Resource
    BlogService blogService;
    @Resource
    JwtUtil util;

    /**
     * 临时变量
     */
    private UserDto registerUser;


    @PostMapping("/register")
    @Override
    public Map<String, Object> register(
            @RequestParam("username") String username,
            @RequestParam("password") String password,
            @RequestParam("email") String email)
    {
        if (util.getToken() != null) {
            return resultUtil.result(500,"请先退出登录,再注册");
        }
        String name = userService.findByUsername(username);
        //名字不为空表示此用户在数据库注册过了
        if (name != null) {
            return resultUtil.result(403, "用户已存在");
        }
        //默认是roleId是3最低等级的
        registerUser = new UserDto(username, password, email, null, null, 3,1,new java.sql.Date(System.currentTimeMillis()));
        emailUtil.sendEmail(email);
        return resultUtil.result(200, "请查看邮件，输入注册码");
    }

    @GetMapping("register/{registerCode}")
    @Override
    public Map<String, Object> registerCode(@PathVariable("registerCode") String registerCode)
    {
        if (emailUtil.getCode().equals(registerCode)) {
            userService.register(registerUser);
            return resultUtil.result(200, "注册成功");
        }
        return resultUtil.result(500, "注册失败，请检查注册码");
    }

    @PostMapping("/login")
    @Override
    public Map<String, Object> login(@RequestParam("username") String username,
                                     @RequestParam("password") String password,
                                     @RequestParam(value = "isRememberMe", required = false) boolean isRememberMe)
    {
        //清除session
        clearSession();
        //判断用户是否存在
        String byUsername = userService.findByUsername(username);
        if (byUsername == null) {
            return resultUtil.result(404, "用户不存在");
        }
        //验证密码是否正确
        UserDto user = userService.login(username, password);
        if (!user.getPassword().equals(password)) {
            return resultUtil.result(404, "密码不正确");
        }
        //设置记住我功能
        if (isRememberMe) {
            //设置token的存活期为半个月这里是毫秒为单位 1000*60*60*24*15
            ModelData.USER_TOKEN = JwtUtil.getToken(user, 1000 * 60 * 60 * 24 * 15);
            Cookie cookie = null;
            //防止重复登录而token却不刷新
            List<Cookie> cookies = Arrays.stream(request.getCookies()).filter(ck -> ck.getName().equals(ConstantField.USER_COOKIE_NAME)).toList();
            if (cookies != null && cookies.size() > 0) {
                cookie = cookies.get(0);
                cookie.setValue(ModelData.USER_TOKEN);
            } else {
                cookie = new Cookie(ConstantField.USER_COOKIE_NAME, ModelData.USER_TOKEN);
            }
            //设置为全局cookie
            cookie.setPath("/");
            //设置不用登录的时间为半个月,这里以秒为单位 60*60*24*15
            cookie.setMaxAge(60 * 60 * 24 * 15);
            response.addCookie(cookie);
        } else {
            //清除cookie
            clearCookie();
            //设置token的存活期为session存活期30分钟这里是毫秒为单位 1000*60*30
            ModelData.USER_TOKEN = JwtUtil.getToken(user, 1000 * 60 * 30);
            //如果没设置就放在session中，浏览器关闭就需要重新登录
            HttpSession session = request.getSession();
            session.setAttribute(ConstantField.USER_COOKIE_NAME, ModelData.USER_TOKEN);
        }

        //没问题就返回登录成功
        return resultUtil.result(200, "登录成功", new Object[]{"token", ModelData.USER_TOKEN, "userInfo", getUserVo(user)});
    }
    @GetMapping("showBlog")
    @Override
    public Map<String, Object> homeShowBlog() {
        List<HomeDto> homeDtoList = blogService.queryAllBlogByTime();
        return resultUtil.result(200,"查询成功",homeDtoList);
    }
    @GetMapping("queryBlog/{uuid}")
    @Override
    public Map<String, Object> queryBlogByUUID(@PathVariable("uuid") String uuid) {
        HomeDto homeDto = blogService.queryBlogByUUID(uuid);
        if (homeDto == null) {
            return resultUtil.result(500,"查询失败，没有这样的博客");
        }
        return resultUtil.result(200,"查询成功",homeDto);
    }
    /**
     * 这种可有可无的数据直接展示
     */
    @Override
    @GetMapping("queryComment/{uuid}")
    public Map<String, Object> queryBlogCommentByUUId(@PathVariable("uuid") String uuid) {
        List<BlogCommentDto> commentList = blogService.queryAllCommentByUUID(uuid);
        return resultUtil.result(200,"查询成功",commentList);
    }

    @Override
    @PostMapping("queryByTitle")
    public Map<String, Object> queryBlogByTitle(@RequestParam("title") String title) {
        List<HomeDto> homeDtoList = blogService.queryAllBlogByTitle(title);
        return resultUtil.result(200,"查询成功",homeDtoList);
    }

    @Override
    @GetMapping("searchUser/{username}")
    public Map<String, Object> searchUser(@PathVariable("username") String username) {
        List<UserDto> someOne = userService.findSomeOne(username);
        List<UserVo> userVos = someOne.stream().map(this::getUserVo).toList();
        return resultUtil.result(200,"查询成功",userVos);
    }


    /**
     * 用户访问了需要的登录的url
     */
    @Operation(summary = "提醒用户需要登录接口")
    @RequestMapping(value = "/NoAuthentication",method = {RequestMethod.DELETE,RequestMethod.GET,RequestMethod.PUT,RequestMethod.POST})
    public Map<String, Object> NoAuthentication()
    {
        return resultUtil.result(404, "未登录，请登录后再访问");
    }

    /**
     * 用户访问了需要的权限的url
     */
    @Operation(summary = "提醒用户权限不够的接口")
    @RequestMapping(value = "/NoAuthorization",method = {RequestMethod.DELETE,RequestMethod.GET,RequestMethod.PUT,RequestMethod.POST})
    public Map<String, Object> NoAuthorization() {
        return resultUtil.result(404, "您没有权限访问此页面");
    }
    /**
     * 用户身份等级不够
     */
    @Operation(summary = "提醒用户等级不够的接口")
    @RequestMapping(value = "/noPermission",method = {RequestMethod.DELETE,RequestMethod.GET,RequestMethod.PUT,RequestMethod.POST})
    public Map<String, Object> NoPermission() {
        return resultUtil.result(404, "你的身份等级不够,需要提升才能做更多的事");
    }
    /**
     * 用于登录的时候，清除已有的session
     */
    public void clearSession() {
        HttpSession session = request.getSession();
        //清除session
        Object attribute = session.getAttribute(ConstantField.USER_COOKIE_NAME);
        if (attribute != null) {
            session.removeAttribute(ConstantField.USER_COOKIE_NAME);
        }
    }

    /**
     * 用于登录的时候，清除已有的cookie
     */
    public void clearCookie() {
        Cookie[] cookies = request.getCookies();
        //清除cookie
        List<Cookie> cookieList = Arrays.stream(cookies).filter(ck -> ck.getName().equals(ConstantField.USER_COOKIE_NAME)).toList();
        if (cookieList != null && cookieList.size() > 0) {
            Cookie cookie = cookieList.get(0);
            cookie.setValue("");
            cookie.setPath("/");
            response.addCookie(cookie);
            cookie.setMaxAge(0);
        }
    }

    /**
     * 返回用户视图对象
     */
    public UserVo getUserVo(UserDto userDto) {
        //设置视图传送对象
        UserVo userVo = new UserVo();
        userVo.setUsername(userDto.getUsername());
        userVo.setRoleName(userDto.getRoleDto().getRoleName());
        userVo.setAuth(userDto.getRoleDto().getRoleRuth());
        userVo.setEmail(userDto.getEmail());
        userVo.setLikes(userService.queryAllFollow(userDto.getUsername()).size());
        userVo.setFollowings(userService.queryAllFollowing(userDto.getUsername()).size());
        userVo.setCollectBlogNumber(blogService.queryAllBlogByUsername(userDto.getUsername()).size());
        userVo.setBirth(userDto.getBirth());
        userVo.setAge(new Date().getYear() - userDto.getBirth().getYear());
        userVo.setGender(userDto.getGender() > 0 ? "男":"女");
        return userVo;
    }

}
